// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

import { Button, Palette } from "std-widgets.slint";

import { Icons } from "icons.slint";

component VirtualKeyboardButton {
    in property <string> key;
    in property <image> icon;

    callback key-pressed(/* key */ string);

    min-width: 32px;
    min-height: 32px;
    horizontal-stretch: 0;

    states [
        pressed when i-touch-area.pressed : {
            i-state-area.opacity: 0.5;
        }
    ]

    i-container := Rectangle {
        border-radius: 4px;
        background: Palette.color-scheme == ColorScheme.dark ? #373737 : #ffffff;

        HorizontalLayout {
            padding: 8px;

            if (root.key != "") : Text {
                text: root.key;
                color: Palette.color-scheme == ColorScheme.dark ? #ffffff : #000000;
                font-size: 12px;
                vertical-alignment: center;
                horizontal-alignment: center;
            }

            if (root.key == "") : Image {
                y: (parent.height - self.height) / 2;
                source: root.icon;
                height: 18px;
                colorize: Palette.color-scheme == ColorScheme.dark ? #ffffff : #000000;
            }
        }
    }

    i-state-area := Rectangle {
        border-radius: i-container.border-radius;
        opacity: 0;
        background: #000000;

        animate opacity { duration: 150ms; }
    }

    i-touch-area := TouchArea {
        pointer-event(event) => {
            if(event.kind == PointerEventKind.down) {
                root.key-pressed(key);
            }
        }
    }
}

export struct KeyModel {
    key: string,
    shift-key: string,
}

export global VirtualKeyboardHandler {
    in property <bool> enabled;

    in property <[[[KeyModel]]]> default-key-sets: [
       [
            [
                { key: "q", shift-key: "Q" },
                { key: "w", shift-key: "W"  },
                { key: "e", shift-key: "E"  },
                { key: "r", shift-key: "R"  },
                { key: "t", shift-key: "T"  },
                { key: "y", shift-key: "Y"  },
                { key: "u", shift-key: "U"  },
                { key: "i", shift-key: "I"  },
                { key: "o", shift-key: "O"  },
                { key: "p", shift-key: "P"  }
            ],
            [
                { key: "a", shift-key: "A" },
                { key: "s", shift-key: "S" },
                { key: "d", shift-key: "D" },
                { key: "f", shift-key: "F" },
                { key: "g", shift-key: "G" },
                { key: "h", shift-key: "H" },
                { key: "j", shift-key: "J" },
                { key: "k", shift-key: "K" },
                { key: "l", shift-key: "L" }
            ],
            [
                { key: "z", shift-key: "Z" },
                { key: "x", shift-key: "X" },
                { key: "c", shift-key: "C" },
                { key: "v", shift-key: "V" },
                { key: "b", shift-key: "B" },
                { key: "n", shift-key: "N" },
                { key: "m", shift-key: "M" },
                { key: ",", shift-key: ";" },
                { key: ".", shift-key: ":" },
                { key: "?", shift-key: "?" }
            ],
       ],
       [
            [
                { key: "1", shift-key: "[" },
                { key: "2", shift-key: "]" },
                { key: "3", shift-key: "{" },
                { key: "4", shift-key: "}" },
                { key: "5", shift-key: "#" },
                { key: "6", shift-key: "%" },
                { key: "7", shift-key: "^" },
                { key: "8", shift-key: "*" },
                { key: "9", shift-key: "+" },
                { key: "0", shift-key: "=" }
            ],
            [
                { key: "-", shift-key: "_" },
                { key: "/", shift-key: "\\" },
                { key: ":", shift-key: "|" },
                { key: ";", shift-key: "~" },
                { key: "(", shift-key: "<" },
                { key: ")", shift-key: ">" },
                { key: "€", shift-key: "$" },
                { key: "&", shift-key: "€" },
                { key: "@", shift-key: "°" },
                { key: "'", shift-key: "#" },
            ],
            [
                { key: ".", shift-key: "." },
                { key: ",", shift-key: "," },
                { key: "?", shift-key: "?" },
                { key: "!", shift-key: "!" },
                { key: "'", shift-key: "'" },
            ],
       ]
    ];

    out property <int> current-key-set;
    out property <[[KeyModel]]> keys: default-key-sets[self.current-key-set];
    in-out property <bool> open;

    callback key_pressed(/* key */ string);

    public function switch-keyboard() {
        if (self.current-key-set < self.default-key-sets.length - 1) {
            self.current-key-set += 1;
        } else {
            self.current-key-set -= 1;
        }

        self.current-key-set = min(self.default-key-sets.length - 1, max(0, self.current-key-set))
    }
}

export component VirtualKeyboard  {
    private property <bool> shift;

    callback close();

    preferred-width: 100%;

    TouchArea {}

    Rectangle {
        background: Palette.color-scheme == ColorScheme.dark ? #1c1c1c : #d4d4d4;
        height: 100%;
    }

    i-layout := VerticalLayout {
        padding: 8px;
        spacing: 4px;

        for row[index] in VirtualKeyboardHandler.keys : HorizontalLayout {
            spacing: 4px;

            if (index == 0) : VirtualKeyboardButton {
                key: "ESC";

                key-pressed => {
                    VirtualKeyboardHandler.key-pressed(Key.Escape);
                }
            }

            if (index == 1) : VirtualKeyboardButton {
                key: "Tab";

                key-pressed => {
                    VirtualKeyboardHandler.key-pressed(Key.Tab);
                }
            }

            // shift
            if (index == 2) : VirtualKeyboardButton {
                icon: Icons.arrow-up;

                key-pressed => {
                    root.shift = !root.shift;
                }
            }

            for km in row : VirtualKeyboardButton {
                key: root.shift ? km.shift-key : km.key;

                key-pressed(key) => {
                    VirtualKeyboardHandler.key-pressed(key);
                    root.shift = false;
                }
            }

            if (index == 0) : VirtualKeyboardButton {
                icon: Icons.chevron-left;

                key-pressed => {
                    VirtualKeyboardHandler.key-pressed(Key.Backspace);
                }
            }

            if (index == 1) : VirtualKeyboardButton {
                icon: Icons.arrow-circle-o-left;

                key-pressed => {
                    VirtualKeyboardHandler.key-pressed(Key.Return);
                }
            }

            // shift
            if (index == 2) : VirtualKeyboardButton {
                icon: Icons.arrow-up;

                key-pressed => {
                    root.shift = !root.shift;
                }
            }
        }

        HorizontalLayout {
            spacing: 4px;

             VirtualKeyboardButton {
                icon: Icons.expand-more;

                key-pressed(key) => {
                    root.close();
                }
            }

            VirtualKeyboardButton {
                icon: Icons.globe;

                key-pressed(key) => {
                    VirtualKeyboardHandler.switch-keyboard();
                }
            }
            VirtualKeyboardButton {
                horizontal-stretch: 1;
                key: " ";

                key-pressed(key) => {
                    root.shift = false;
                    VirtualKeyboardHandler.key-pressed(key);
                }
            }
            VirtualKeyboardButton {
                icon: Icons.arrow-left;

                key-pressed(key) => {
                    VirtualKeyboardHandler.key-pressed(Key.LeftArrow);
                }
            }
            VirtualKeyboardButton {
                icon: Icons.arrow-right;

                key-pressed(key) => {
                    VirtualKeyboardHandler.key-pressed(Key.RightArrow);
                }
            }
        }


    }

    animate y { duration: 500ms; easing: cubic-bezier(0.05, 0.7, 0.1, 1.0); }
}
